home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Libraries
/
Mac Stdg 4.4 Folder
/
Samples
/
bullwins.c
< prev
next >
Wrap
Text File
|
1994-01-09
|
7KB
|
325 lines
/* window.c - this is where it all happens */
#include <stdlib.h>
#include "stdg.h"
#include "bullseye.h"
#define OFFSCREEN 1 /* 1=use offscreen buffers for every window */
/* 0=draw directly to each window */
short wincount = 0; /* how many windows do we have */
enum Shapes { /* what shape does a window bullseye have */
OVAL = 0,
RECTANGLE = 1,
TRIANGLE = 2
};
typedef struct Winfo Winfo; /* private bullseye window information */
struct Winfo {
short shape;
short width;
pixval fg;
pixval bg;
#if OFFSCREEN
bitmap * b;
short changed;
#endif
};
#define winfo(w) ((Winfo *) w->data)
cursor watch={
{ -9, -8},
{0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0,
0x7F, 0xE0, 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF8,
0xFF, 0xF8, 0xFF, 0xF0, 0xFF, 0xF0, 0x7F, 0xE0,
0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0, 0x3F, 0xC0,
},
{0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80,
0x20, 0x40, 0x42, 0x20, 0x42, 0x20, 0x42, 0x30,
0x4E, 0x30, 0x40, 0x20, 0x40, 0x20, 0x20, 0x40,
0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80, 0x1F, 0x80,
},
0
};
/*
* The next six functions are the function-call interface to
* bullseye windows. The above data structures are private to
* this file, and don't need to be known by anyone else.
*/
void set_width(window *w, short width) /* set line width */
{
#if OFFSCREEN
winfo(w)->changed = 1;
#endif
winfo(w)->width = width;
fill_rect(w->b, w->b->r, WHITE);
redraw(w);
}
void set_fore(window *w, pixval v) /* set foreground colour */
{
#if OFFSCREEN
winfo(w)->changed = 1;
#endif
winfo(w)->fg = v;
fill_rect(w->b, w->b->r, WHITE);
redraw(w);
}
void set_back(window *w, pixval v) /* set background colour */
{
#if OFFSCREEN
winfo(w)->changed = 1;
#endif
winfo(w)->bg = v;
fill_rect(w->b, w->b->r, WHITE);
redraw(w);
}
short get_width(window *w) /* get width of lines in window */
{
return winfo(w)->width;
}
pixval get_fore(window *w) /* get foreground colour */
{
return winfo(w)->fg;
}
pixval get_back(window *w) /* get background colour */
{
return winfo(w)->bg;
}
rectangle nice_rect(void) /* return a nice new rectangle for a window */
{
long offset;
rectangle r = rdiag(25,45,100,100);
offset = ((wincount) % 7) * 20;
r = raddp(r,pt(offset,offset));
wincount++;
return r;
}
/*
* New_bullseye creates a basic bullseye window and returns it.
* The next three functions customise it to a given shape.
* The function relies on the nice_rect function to provide a nice
* location for a bullseye on screen.
*/
window *new_bullseye(short shape) /* make and return a bullseye window */
{
window *w;
rectangle r = nice_rect();
w = new_window("Bullseye", r,
Titlebar | Closebox | Maximize | Resize | Document);
set_winfns(w, &close, &resize, &redraw);
w->data = (void *) malloc(sizeof(Winfo));
winfo(w)->shape = shape;
winfo(w)->width = 5;
winfo(w)->fg = BLACK;
winfo(w)->bg = WHITE;
#if OFFSCREEN
winfo(w)->b = new_bitmap(r, 0); /* bitmap size & depth of window */
winfo(w)->changed = 1; /* remember that this window needs redrawing */
#endif
return w;
}
void new_oval(void) /* create new oval shape and show it */
{
window *w = new_bullseye(OVAL);
set_winname(w, "Oval");
show_window(w);
}
void new_rectangle(void) /* create new rectangular shape and show it */
{
window *w = new_bullseye(RECTANGLE);
set_winname(w, "Rectangle");
show_window(w);
}
void new_triangle(void) /* create new triangular shape and show it */
{
window *w = new_bullseye(TRIANGLE);
set_winname(w, "Triangle");
show_window(w);
}
/*
* This function is called from main when someone does a mouse click
* in a bullseye window.
*/
void hit_window(window *w) /* handle mouse down in the window */
{
fill_rect(w->b, w->b->r, WHITE);
redraw(w);
}
/*
* Close happens whenever a bullseye window is closed.
*/
void close(window *w) /* close a window */
{
#if OFFSCREEN
del_bitmap(winfo(w)->b);
#endif
free(w->data);
del_window(w);
}
/*
* Paint_oval is the expert that knows how to paint a single oval
* of a given thickness, colour and size to a bitmap.
*/
void paint_oval(bitmap *b, rectangle r, short width, pixval v)
{
point p0;
long r1, r2;
short w;
p0 = divp(addp(r.min,r.max),2);
r1 = dx(r)/2;
r2 = dy(r)/2;
w = width;
while(w > 0) {
draw_ellipse(b, p0, r1, r2, v);
r1--;
r2--;
w--;
}
}
/*
* Paint_rectangle uses draw_rect, which uses fill_rect. This makes
* it faster than the other drawing operations.
*/
void paint_rectangle(bitmap *b, rectangle r, short width, pixval v)
{
short w;
w = width;
if (w > dx(r))
w = dx(r);
if (w > dy(r))
w = dy(r);
draw_rect(b, r, w, v);
}
/*
* Paint_triangle is similar to the THINK C Bullseye triangle shape.
* It doesn't draw properly inset triangles due to the way the
* target rectangle is stepped inwards.
*/
void paint_triangle(bitmap *b, rectangle r, short width, pixval v)
{
point p1, p2, p3;
short w;
p1 = r.min;
p2 = pt(r.min.x, r.max.y);
p3 = r.max;
w = width;
while(w > 0) {
draw_line(b, p1, p2, v);
draw_line(b, p2, p3, v);
draw_line(b, p3, p1, v);
p1 = addp(p1,pt(1,2));
p2 = addp(p2,pt(1,-1));
p3 = addp(p3,pt(-2,-1));
w--;
}
}
/*
* Resize is called when a window is resized. Redraw is called afterwards.
* Here we change the size of the window's offscreen buffer.
*/
void resize(window *w)
{
#if OFFSCREEN
winfo(w)->changed = 1;
del_bitmap(winfo(w)->b);
winfo(w)->b = new_bitmap(w->r, 0);
#endif
}
/*
* Draw does the drawing to a bitmap (could be the window bitmap).
* It is given some bullseye info and calls the appropriate
* paint_shape function repeatedly with inward stepping rectangles.
*/
void draw(bitmap *b, short width, short shape, pixval fg, pixval bg)
{
rectangle r = b->r;
set_cursor(&watch);
fill_rect(b, r, bg); /* draw background colour */
while(dx(r) > 0 && dy(r) > 0) { /* step rectangle inwards */
switch (shape) {
case OVAL: paint_oval(b, r, width, fg); break;
case RECTANGLE: paint_rectangle(b, r, width, fg); break;
case TRIANGLE: paint_triangle(b, r, width, fg); break;
}
r = insetr(r, width*2);
}
set_cursor(NULL);
}
/*
* Redraw is called whenever a window needs redrawing.
* It calls draw if drawing directly to the window, or if the offscreen
* bitmap needs redrawing.
* It calls bit_copy to refresh the window from the offscreen bitmap,
* if an offscreen bitmap exists.
*/
void redraw(window *w)
{
#if OFFSCREEN
if (winfo(w)->changed) {
draw(winfo(w)->b, winfo(w)->width, winfo(w)->shape,
winfo(w)->fg, winfo(w)->bg);
winfo(w)->changed = 0;
}
bit_copy(w->b, pt(0,0), winfo(w)->b, winfo(w)->b->r, S);
#else
draw(w->b, winfo(w)->width, winfo(w)->shape,
winfo(w)->fg, winfo(w)->bg);
#endif
}